from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, 
                           QPushButton, QLineEdit, QComboBox, QFrame,
                           QScrollArea, QProgressBar, QMessageBox, QSpinBox)
from PyQt6.QtCore import Qt, pyqtSignal, QThread, QUrl, QTimer
from .base_page import BasePage, ContentCard
import os
import json
import time
from pathlib import Path
import requests
from bs4 import BeautifulSoup
import re
from urllib.parse import urlparse, urljoin
from concurrent.futures import ThreadPoolExecutor, as_completed
import threading
import queue
import urllib3
import certifi
import random

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

class ChapterDownloader:
    """章节下载器"""
    def __init__(self, url, headers, timeout=10):
        self.url = url
        self.headers = headers
        self.timeout = timeout
        self.content = None
        self.error = None
        
    def download(self):
        try:
            response = requests.get(
                self.url, 
                headers=self.headers, 
                timeout=self.timeout,
                verify=False
            )
            response.encoding = response.apparent_encoding or 'utf-8'
            soup = BeautifulSoup(response.text, 'html.parser')
            
            # 尝试不同的内容选择器
            content_selectors = [
                '#content',
                '.chapter-content',
                '.article-content',
                '.txt',
                '.content'
            ]
            
            for selector in content_selectors:
                content_elem = soup.select_one(selector)
                if content_elem:
                    self.content = content_elem.text.strip()
                    break
                    
            if not self.content:
                self.error = "无法获取章节内容"
                
        except Exception as e:
            self.error = str(e)

class NovelDownloader(QThread):
    progress_updated = pyqtSignal(int, int)  # 当前章节, 总章节
    status_updated = pyqtSignal(str)  # 状态信息
    download_complete = pyqtSignal(dict)  # 下载完成的书籍信息
    error_occurred = pyqtSignal(str)  # 错误信息

    def __init__(self, url, source, save_path):
        super().__init__()
        self.url = url
        self.source = source
        self.save_path = save_path
        self.is_running = True
        
        # 动态下载配置
        self.max_workers = 100       # 增加初始线程数到100
        self.min_workers = 20        # 最小线程数
        self.current_workers = 100   # 当前线程数
        self.batch_size = 20         # 增加批量大小
        self.retry_times = 3         # 重试次数
        self.timeout = 5             # 超时时间
        self.delay = 0.05           # 减少初始延迟
        self.min_delay = 0.02       # 最小延迟
        self.max_delay = 0.5        # 最大延迟
        self.success_count = 0      # 成功计数
        self.fail_count = 0         # 失败计数
        self.adjust_interval = 50    # 每50个请求调整一次参数
        
        # 配置请求头
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
            'Connection': 'keep-alive',
            'Cache-Control': 'max-age=0'
        }
        
        # 创建Session以复用连接
        self.session = requests.Session()
        self.session.headers.update(self.headers)
        
        # 使用certifi提供的证书
        self.session.verify = certifi.where()
        
        # 配置重试策略
        retry_strategy = requests.adapters.Retry(
            total=3,  # 最大重试次数
            backoff_factor=0.1,  # 重试间隔
            status_forcelist=[500, 502, 503, 504]  # 需要重试的HTTP状态码
        )
        
        # 配置连接池
        adapter = requests.adapters.HTTPAdapter(
            max_retries=retry_strategy,
            pool_connections=100,
            pool_maxsize=100
        )
        self.session.mount("http://", adapter)
        self.session.mount("https://", adapter)

    def adjust_parameters(self):
        """动态调整下载参数"""
        total = self.success_count + self.fail_count
        if total >= self.adjust_interval:
            success_rate = self.success_count / total
            
            # 根据成功率调整参数
            if success_rate > 0.95:  # 非常成功，加快速度
                self.current_workers = min(self.current_workers + 10, self.max_workers)
                self.delay = max(self.delay * 0.8, self.min_delay)
                self.batch_size = min(self.batch_size + 2, 30)
            elif success_rate > 0.8:  # 较为成功，小幅提升
                self.current_workers = min(self.current_workers + 5, self.max_workers)
                self.delay = max(self.delay * 0.9, self.min_delay)
            elif success_rate < 0.5:  # 失败率高，降低速度
                self.current_workers = max(self.current_workers - 10, self.min_workers)
                self.delay = min(self.delay * 1.5, self.max_delay)
                self.batch_size = max(self.batch_size - 2, 10)
            
            # 重置计数
            self.success_count = 0
            self.fail_count = 0

    def run(self):
        try:
            # 根据不同源选择不同的下载方法
            if self.source == "笔趣阁":
                book_info = self.download_biquge()
            elif self.source == "起点中文网":
                book_info = self.download_qidian()
            # ... 其他源的下载方法
            
            self.download_complete.emit(book_info)
            
        except Exception as e:
            self.error_occurred.emit(str(e))

    def download_chapter_batch(self, chapters, batch_size=None):
        """批量下载章节"""
        if batch_size is None:
            batch_size = self.batch_size
            
        total_chapters = len(chapters)
        results = {}
        download_errors = []
        
        # 创建线程池
        with ThreadPoolExecutor(max_workers=self.current_workers) as executor:
            # 分批处理章节
            for i in range(0, total_chapters, batch_size):
                if not self.is_running:
                    break
                    
                batch = chapters[i:i + batch_size]
                futures = []
                
                # 提交批量下载任务
                for j, chapter in enumerate(batch):
                    chapter_index = i + j
                    chapter_url = chapter['href']  # 使用字典访问
                    chapter_title = chapter['title']  # 使用字典访问
                    
                    future = executor.submit(
                        self.download_single_chapter,
                        chapter_url,
                        chapter_title,
                        chapter_index
                    )
                    futures.append(future)
                
                # 等待当前批次完成
                for future in as_completed(futures):
                    try:
                        result = future.result()
                        if result['success']:
                            results[result['index']] = (
                                result['title'],
                                result['content']
                            )
                            self.success_count += 1
                        else:
                            download_errors.append(
                                f"{result['title']}: {result['error']}"
                            )
                            self.fail_count += 1
                        
                        # 更新进度
                        self.progress_updated.emit(len(results), total_chapters)
                        self.status_updated.emit(f"正在下载: {result['title']}")
                        
                        # 动态调整参数
                        self.adjust_parameters()
                        
                    except Exception as e:
                        print(f"处理下载结果时出错: {str(e)}")
                        self.fail_count += 1
                
                # 批次间短暂延迟
                time.sleep(self.delay)
        
        return results, download_errors

    def download_single_chapter(self, url, title, index):
        """下载单个章节"""
        try:
            # 添加随机延迟，避免被反爬
            time.sleep(random.uniform(0.1, 0.3))
            
            # 更新请求头，模拟浏览器行为
            headers = {
                'User-Agent': random.choice([
                    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/91.0.864.59 Safari/537.36',
                    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0'
                ]),
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
                'Cache-Control': 'no-cache',
                'Pragma': 'no-cache',
                'Referer': self.url
            }
            self.session.headers.update(headers)
            
            # 根据域名决定是否验证证书
            domain = urlparse(url).netloc
            verify = False if domain in ['www.bq04.cc'] else certifi.where()
            
            response = self.session.get(
                url,
                timeout=self.timeout,
                verify=verify
            )
            
            # 尝试多种编码
            content_text = None
            for encoding in ['utf-8', 'gbk', 'gb2312']:
                try:
                    response.encoding = encoding
                    text = response.text
                    # 检查是否有乱码
                    if not '' in text and len(text.strip()) > 0:
                        content_text = text
                        break
                except:
                    continue
            
            if not content_text:
                # 如果所有编码都失败，使用apparent_encoding
                response.encoding = response.apparent_encoding
                content_text = response.text
            
            if response.status_code == 200:
                soup = BeautifulSoup(content_text, 'html.parser')
                
                # 尝试多个内容选择器
                content_selectors = [
                    '#content',
                    '.chapter-content',
                    '#chaptercontent',
                    '.showtxt',
                    '#txtContent',
                    '.read-content'
                ]
                
                content = None
                for selector in content_selectors:
                    content_elem = soup.select_one(selector)
                    if content_elem:
                        content = content_elem.get_text('\n')
                        if content and len(content.strip()) > 100:  # 确保内容长度合理
                            break
                
                if not content:
                    return {
                        'success': False,
                        'title': title,
                        'index': index,
                        'error': '无法获取章节内容'
                    }
                
                # 清理内容
                content = self.clean_chapter_content(content)
                
                # 验证内容有效性
                if len(content.strip()) < 100:
                    return {
                        'success': False,
                        'title': title,
                        'index': index,
                        'error': '章节内容异常'
                    }
                
                return {
                    'success': True,
                    'title': title,
                    'index': index,
                    'content': content
                }
                
        except requests.exceptions.Timeout:
            return {
                'success': False,
                'title': title,
                'index': index,
                'error': '下载超时'
            }
        except requests.exceptions.RequestException as e:
            return {
                'success': False,
                'title': title,
                'index': index,
                'error': f'网络错误: {str(e)}'
            }
        except Exception as e:
            return {
                'success': False,
                'title': title,
                'index': index,
                'error': str(e)
            }

    def download_biquge(self):
        try:
            # 获取书籍页面
            response = self.session.get(self.url, timeout=self.timeout)
            response.encoding = response.apparent_encoding or 'utf-8'
            soup = BeautifulSoup(response.text, 'html.parser')
            
            # 调试输出
            print("正在解析页面...")
            
            # 尝试多个标题选择器
            title_selectors = [
                '#info h1',
                '.book-title h1',
                '.bookinfo h1',
                'h1.bookname',
                '.book-name',
                '#bookname',
                'h1',
            ]
            
            # 尝试多个作者选择器
            author_selectors = [
                '#info p:contains("作者")',
                '.book-title p:contains("作者")',
                '.author',
                '.writer',
                'p:contains("作者")',
                'div:contains("作者")',
            ]
            
            # 获取标题
            title = None
            for selector in title_selectors:
                title_elem = soup.select_one(selector)
                if title_elem:
                    title = title_elem.text.strip()
                    if title:
                        print(f"找到标题: {title}")
                        break
            
            if not title:
                raise Exception("无法获取书籍标题")
            
            # 获取作者
            author = "未知作者"
            for selector in author_selectors:
                author_elem = soup.select_one(selector)
                if author_elem:
                    author_text = author_elem.text.strip()
                    # 尝试提取作者名
                    if "作者" in author_text:
                        author = author_text.split("作者")[-1].strip('：: ')
                    else:
                        author = author_text
                    if author:
                        print(f"找到作者: {author}")
                        break
            
            print(f"找到书籍信息 - 标题: {title}, 作者: {author}")
            
            # 获取章节列表并去重
            chapters = []
            seen_urls = set()
            seen_titles = {}
            
            # 获取章节列表容器
            chapter_list = soup.select_one('#list, .listmain, #chapters-list')
            if not chapter_list:
                raise Exception("无法找到章节列表")
            
            # 只获取章节列表中的链接
            chapter_elements = chapter_list.select('dd a, li a')
            
            for chapter in chapter_elements:
                chapter_url = urljoin(self.url, chapter.get('href', ''))
                chapter_title = chapter.text.strip()
                
                # 跳过无效的URL和标题
                if not chapter_url or not chapter_title:
                    continue
                    
                # 跳过目录、上一章、下一章等链接
                if any(skip in chapter_title for skip in ['目录', '上一章', '下一章', '最新章节']):
                    continue
                    
                # 跳过重复的URL
                if chapter_url in seen_urls:
                    continue
                    
                # 处理重复的标题
                if chapter_title in seen_titles:
                    continue
                    
                # 添加新章节
                chapters.append({
                    'href': chapter_url,
                    'title': chapter_title
                })
                seen_urls.add(chapter_url)
                seen_titles[chapter_title] = chapter_url
            
            if not chapters:
                raise Exception("未找到有效的章节链接")
                
            print(f"总共找到 {len(chapters)} 个章节")
            
            # 对章节进行排序
            def extract_chapter_number(chapter):
                # 从标题中提取数字
                numbers = re.findall(r'\d+', chapter['title'])
                return int(numbers[0]) if numbers else 0
                
            chapters.sort(key=extract_chapter_number)
            
            # 下载章节内容
            book_dir = Path(self.save_path)
            book_dir.mkdir(parents=True, exist_ok=True)
            
            # 批量下载章节
            results, download_errors = self.download_chapter_batch(chapters)
            
            # 检查下载结果
            if not results:
                raise Exception("所有章节下载失败")
                
            # 组织内容并保存
            content = f"书名：{title}\n作者：{author}\n\n"
            
            # 按章节顺序组织内容，跳过空章节
            for i in range(len(chapters)):
                if i in results:
                    chapter_title, chapter_content = results[i]
                    # 检查章节内容是否为空
                    if chapter_content and len(chapter_content.strip()) > 0:
                        content += f"\n{chapter_title}\n\n{chapter_content}\n"
            
            # 保存文件
            save_path = book_dir / f"{title}.txt"
            with open(save_path, 'w', encoding='utf-8') as f:
                f.write(content)
            
            # 如果有下载失败的章节，添加到文件末尾
            if download_errors:
                error_content = "\n\n下载失败的章节：\n" + "\n".join(download_errors)
                with open(save_path, 'a', encoding='utf-8') as f:
                    f.write(error_content)
            
            return {
                'title': title,
                'author': author,
                'path': str(save_path),
                'total_chapters': len(chapters),
                'success_chapters': len(results),
                'failed_chapters': len(download_errors),
                'source': self.source,
                'url': self.url
            }
            
        except Exception as e:
            print(f"下载失败，错误信息: {str(e)}")  # 添加错误日志
            raise Exception(f"下载失败: {str(e)}")

    def is_valid_chapter_title(self, title):
        """验证章节标题的有效性"""
        # 常见的章节标题模式
        chapter_patterns = [
            # 第X章 标题
            r'^第[0-9零一二三四五六七八九十百千万]+章\s*.*$',
            # 第X节 标题
            r'^第[0-9零一二三四五六七八九十百千万]+节\s*.*$',
            # 正文 第X章 标题
            r'^正文\s*第[0-9零一二三四五六七八九十百千万]+章\s*.*$',
            # 章节号 标题（如：1. 标题）
            r'^\d+\.\s*第.*章.*$',
            # 纯数字+标题（如：1. 某某某）
            r'^\d+[\s\.、]\S+.*$',
            # 第X回 标题
            r'^第[0-9零一二三四五六七八九十百千万]+回\s*.*$',
            # 序章、终章等
            r'^(序章|楔子|正文|终章|尾声|后记|番外|附录).*$',
            # 卷名
            r'^第[0-9零一二三四五六七八九十百千万]+卷\s*.*$',
            # 英文章节格式
            r'^Chapter\s*\d+\s*[:：].*$',
            # 纯数字章节（至少2位数）
            r'^\d{2,}\s*[、.\s].*$',
            # 通用数字开头格式
            r'^\d+[、\s\.。:：]\s*\S+.*$'
        ]
        
        # 排除明显不是章节标题的情况
        invalid_patterns = [
            # 单个数字的列表项
            r'^\d\s*$',
            # 空白标题
            r'^\s*$',
            # 纯符号
            r'^[\.\-\*\#\@\[\]\(\)（）【】]+$',
            # 过短的内容（小于2个字符）
            r'^.{1,2}$',
            # HTML标签
            r'^<[^>]+>$',
            # 广告内容
            r'.*(广告|推广|链接|下载|APP|app|请记住|收藏|手机版).*$'
        ]
        
        # 如果匹配任何无效模式，返回False
        for pattern in invalid_patterns:
            if re.match(pattern, title):
                return False
        
        # 检查标题是否匹配任一章节模式
        for pattern in chapter_patterns:
            if re.match(pattern, title):
                return True
        
        # 对于其他情况，进行额外检查
        # 1. 检查标题长度
        if len(title.strip()) < 4:
            return False
        
        # 2. 检查是否包含数字（大多数章节标题都包含数字）
        has_number = bool(re.search(r'\d', title))
        
        # 3. 检查是否以常见的章节开头词开始
        common_starts = ['第', '章', '节', '卷', '回', '部', '篇', '集']
        starts_with_common = any(title.startswith(word) for word in common_starts)
        
        # 4. 检查是否只是简单的数字列表项
        is_simple_list = bool(re.match(r'^\d+[\.\、]$', title))
        
        # 如果不是简单的列表项，且（包含数字或以常见章节词开头），则认为是有效的章节标题
        if not is_simple_list and (has_number or starts_with_common):
            return True
        
        # 默认返回False
        return False

    def clean_chapter_content(self, content):
        """清理章节内容"""
        if not content:
            return ""
        
        # 移除常见的广告和无用文本
        ad_patterns = [
            r'笔趣阁.*?最快更新',
            r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+',
            r'www\.[a-zA-Z0-9]+\.[a-zA-Z]+',
            r'手机用户请访问.*?阅读',
            r'本章未完.*?下一页继续阅读',
            r'温馨提示：.*?最新章节！',
            r'热门推荐：.*',
            r'最新章节全文阅读.*',
            r'请记住本书首发域名：.*',
            r'txt下载.*',
            r'手机阅读.*',
            r'为了方便下次阅读.*',
            r'章节错误,点此举报.*',
            r'【推荐下载.*?】',
            r'\(adsbygoogle.*?\)',
            r'<!--.*?-->',
            r'<script>.*?</script>'
        ]
        
        # 移除广告
        for pattern in ad_patterns:
            content = re.sub(pattern, '', content, flags=re.IGNORECASE | re.DOTALL)
        
        # 基本清理
        content = re.sub(r'\s+', '\n', content)  # 统一换行符
        content = re.sub(r'\n{3,}', '\n\n', content)  # 移除过多的空行
        
        # 移除空行和首尾空白
        lines = [line.strip() for line in content.split('\n')]
        lines = [line for line in lines if line]
        
        return '\n'.join(lines)

    def stop(self):
        self.is_running = False

class NovelDownloadPage(BasePage):
    def __init__(self):
        super().__init__()
        self.set_title("小说下载")
        self.downloader = None
        self.init_ui()
        
        # 加载设置
        self.load_settings()
    
    def init_ui(self):
        # 创建主布局
        content_layout = QVBoxLayout()
        content_layout.setSpacing(20)
        
        # 创建下载设置卡片
        download_card = ContentCard()
        download_layout = QVBoxLayout(download_card)
        
        # 源选择
        source_layout = QHBoxLayout()
        source_label = QLabel("小说来源:")
        self.source_combo = QComboBox()
        self.source_combo.addItems([
            "笔趣阁",
            "起点中文网",
            "纵横中文网",
            "17K小说网",
            "红袖添香",
            "晋江文学城"
        ])
        source_layout.addWidget(source_label)
        source_layout.addWidget(self.source_combo)
        source_layout.addStretch()
        
        # URL输入
        url_layout = QHBoxLayout()
        url_label = QLabel("小说网址:")
        self.url_input = QLineEdit()
        self.url_input.setPlaceholderText("请输入小说链接或ID")
        url_layout.addWidget(url_label)
        url_layout.addWidget(self.url_input)
        
        # 下载按钮
        self.download_btn = QPushButton("开始下载")
        self.download_btn.clicked.connect(self.start_download)
        url_layout.addWidget(self.download_btn)
        
        # 添加到下载卡片
        download_layout.addLayout(source_layout)
        download_layout.addLayout(url_layout)
        
        # 添加下载卡片到主布局
        content_layout.addWidget(download_card)
        
        # 创建下载列表卡片
        list_card = ContentCard()
        list_layout = QVBoxLayout(list_card)
        
        # 下载列表标题
        list_header = QHBoxLayout()
        list_title = QLabel("下载列表")
        list_title.setStyleSheet("font-size: 16px; font-weight: bold;")
        clear_btn = QPushButton("清空列表")
        clear_btn.clicked.connect(self.clear_download_list)
        list_header.addWidget(list_title)
        list_header.addStretch()
        list_header.addWidget(clear_btn)
        
        # 下载列表滚动区域
        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll.setStyleSheet("QScrollArea { border: none; }")
        
        self.download_list = QWidget()
        self.download_list_layout = QVBoxLayout(self.download_list)
        self.download_list_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
        scroll.setWidget(self.download_list)
        
        # 添加到列表卡片
        list_layout.addLayout(list_header)
        list_layout.addWidget(scroll)
        
        # 添加列表卡片到主布局
        content_layout.addWidget(list_card)
        
        # 设置主布局
        self.main_layout.addLayout(content_layout)
    
    def load_settings(self):
        try:
            with open('settings.json', 'r', encoding='utf-8') as f:
                self.settings = json.load(f)
        except Exception as e:
            QMessageBox.warning(self, "错误", f"加载设置失败: {str(e)}")
            self.settings = {}
    
    def start_download(self):
        url = self.url_input.text().strip()
        if not url:
            QMessageBox.warning(self, "错误", "请输入小说链接或ID")
            return
        
        source = self.source_combo.currentText()
        save_path = self.settings.get('paths', {}).get('novel_download', 'downloads')
        
        # 创建下载进度项
        progress_item = self.create_progress_item("准备下载...")
        
        # 创建下载器
        self.downloader = NovelDownloader(url, source, save_path)
        self.downloader.progress_updated.connect(lambda current, total: 
            self.update_progress(progress_item, current, total))
        self.downloader.status_updated.connect(lambda status:
            self.update_status(progress_item, status))
        self.downloader.download_complete.connect(lambda book_info:
            self.download_finished(progress_item, book_info))
        self.downloader.error_occurred.connect(lambda error:
            self.download_error(progress_item, error))
        
        # 开始下载
        self.downloader.start()
        
        # 禁用下载按钮
        self.download_btn.setEnabled(False)
    
    def create_progress_item(self, initial_status):
        # 创建进度项容器
        item = QFrame()
        item.setStyleSheet("""
            QFrame {
                background: rgba(255, 255, 255, 0.05);
                border-radius: 4px;
                padding: 10px;
                margin: 5px 0;
            }
        """)
        
        layout = QVBoxLayout(item)
        layout.setSpacing(5)
        
        # 状态标签
        status_label = QLabel(initial_status)
        layout.addWidget(status_label)
        
        # 进度条
        progress_bar = QProgressBar()
        progress_bar.setTextVisible(True)
        layout.addWidget(progress_bar)
        
        # 添加到下载列表
        self.download_list_layout.insertWidget(0, item)
        
        return {
            'widget': item,
            'status': status_label,
            'progress': progress_bar
        }
    
    def update_progress(self, item, current, total):
        item['progress'].setMaximum(total)
        item['progress'].setValue(current)
        percentage = int(current / total * 100)
        item['progress'].setFormat(f"{percentage}% ({current}/{total})")
    
    def update_status(self, item, status):
        item['status'].setText(status)
    
    def download_finished(self, item, book_info):
        """下载完成后的处理"""
        try:
            # 更新状态
            self.update_status(item, "下载完成")
            item['progress'].setValue(item['progress'].maximum())
            
            # 导入到书架
            self.import_to_bookshelf(book_info)
            
            # 恢复下载按钮
            self.download_btn.setEnabled(True)
            
            # 显示完成消息
            QMessageBox.information(self, "完成", "小说下载完成并已添加到书架")
            
            # 立即刷新书架 - 使用 QTimer 确保在主线程中执行
            QTimer.singleShot(0, self.refresh_bookshelf)
                
        except Exception as e:
            print(f"下载完成处理失败: {str(e)}")
            
    def refresh_bookshelf(self):
        """刷新书架"""
        try:
            main_window = self.window()
            if main_window and hasattr(main_window, 'novel_page'):
                # 强制重新加载书架数据
                main_window.novel_page.load_books()
                # 强制刷新UI
                main_window.novel_page.bookshelf.refresh_bookshelf()
                # 强制更新布局
                main_window.novel_page.bookshelf.grid_layout.update()
        except Exception as e:
            print(f"刷新书架失败: {str(e)}")
    
    def download_error(self, item, error):
        # 更新状态
        self.update_status(item, f"下载失败: {error}")
        item['widget'].setStyleSheet("""
            QFrame {
                background: rgba(255, 0, 0, 0.1);
                border-radius: 4px;
                padding: 10px;
                margin: 5px 0;
            }
        """)
        
        # 恢复下载按钮
        self.download_btn.setEnabled(True)
    
    def import_to_bookshelf(self, book_info):
        """导入书籍到书架"""
        try:
            current_time = int(time.time())
            print(f"\n导入书籍: {book_info['title']}")
            
            bookshelf_path = Path("data/bookshelf.json")
            bookshelf_path.parent.mkdir(parents=True, exist_ok=True)
            
            if bookshelf_path.exists():
                with open(bookshelf_path, 'r', encoding='utf-8') as f:
                    bookshelf_data = json.load(f)
            else:
                bookshelf_data = {"books": [], "display_settings": {"card_size": 150}}
            
            # 检查是否已存在相同书籍
            book_exists = False
            for book in bookshelf_data['books']:
                if book['title'] == book_info['title']:
                    # 如果书籍已存在，更新时间戳使其排在最前面
                    book['last_read_time'] = current_time
                    book_exists = True
                    print(f"更新已存在书籍时间戳: {book['title']}")
                    break
            
            if not book_exists:
                # 创建新书籍记录
                new_book = {
                    'id': str(current_time),  # 使用时间戳作为ID
                    'title': book_info['title'],
                    'author': book_info.get('author', ''),
                    'path': book_info['path'],
                    'cover': '',
                    'progress': 0,
                    'last_position': 0,
                    'total_chapters': book_info.get('total_chapters', 0),
                    'current_chapter': 0,
                    'add_time': time.strftime('%Y-%m-%d %H:%M:%S'),
                    'last_read_time': current_time  # 新书默认排在最前面
                }
                bookshelf_data['books'].append(new_book)
                print(f"添加新书籍: {new_book['title']}")
            
            # 保存书架数据
            with open(bookshelf_path, 'w', encoding='utf-8') as f:
                json.dump(bookshelf_data, f, ensure_ascii=False, indent=2)
            
            print(f"书籍导入成功: {book_info['title']}, last_read_time: {current_time}\n")
            
            # 通知主窗口刷新书架
            main_window = self.window()
            if main_window and hasattr(main_window, 'novel_page'):
                main_window.novel_page.load_books()
            
        except Exception as e:
            print(f"导入书架失败: {str(e)}")
            raise
    
    def clear_download_list(self):
        # 清空下载列表
        while self.download_list_layout.count():
            item = self.download_list_layout.takeAt(0)
            if item.widget():
                item.widget().deleteLater()

    def format_novel_content(self, content):
        """格式化小说内容，让每句话都变成一行"""
        try:
            # 分段处理
            paragraphs = content.split('\n')
            formatted_paragraphs = []
            
            for para in paragraphs:
                if not para.strip():
                    continue
                    
                # 处理每个段落
                sentences = []
                current_sentence = ''
                in_quote = False
                
                # 逐字符处理
                for i, char in enumerate(para):
                    current_sentence += char
                    
                    # 处理引号
                    if char == '"':
                        in_quote = not in_quote
                    
                    # 在句号、感叹号、问号处分句，但不分割引号内的内容
                    if not in_quote and char in '。！？':
                        if current_sentence.strip():
                            sentences.append(current_sentence.strip())
                        current_sentence = ''
                
                # 处理最后一个句子
                if current_sentence.strip():
                    sentences.append(current_sentence.strip())
                
                # 将处理后的句子添加到结果中
                formatted_paragraphs.extend(sentences)
            
            # 用换行符连接所有句子
            return '\n'.join(formatted_paragraphs)
            
        except Exception as e:
            print(f"格式化内容失败: {str(e)}")
            return content

    def save_chapter(self, book_dir, chapter_title, content):
        """保存章节内容"""
        try:
            # 格式化内容
            formatted_content = self.format_novel_content(content)
            
            # 创建章节文件
            file_path = os.path.join(book_dir, f"{chapter_title}.txt")
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(formatted_content)
                
        except Exception as e:
            print(f"保存章节失败: {str(e)}") 